package org.argeproje.resim.proc.tools;

import java.util.ArrayList;

import org.argeproje.resim.proc.Processor;


public class ProcessorNode {
	protected ArrayList<ArrayList<Connection>> _outConnections;
	protected ArrayList<Connection> _inConnections;
	protected Processor _processor;
	public ProcessorNode(Processor pr) {
		setProcessor(pr);
		//Create default empty connections for each pin
		_inConnections = new ArrayList<Connection>(pr.getConnectionRule().getNoInputs());
		_outConnections = new ArrayList<ArrayList<Connection>>(pr.getConnectionRule().getNoOutputs());
		for (int i = 0; i < getNoOutputs(); i++) {
			_outConnections.add(new ArrayList<Connection>());
		}
		for (int i = 0; i < getNoInputs(); i++) {
			_inConnections.add(new Connection());
		}
	}
		
	private void setProcessor(Processor pr) {
		_processor = pr;
	}

	public Processor getProcessor() {
		return _processor;
	}

	public int getNodeId() {
		return _processor.getId();
	}

	public ArrayList<Connection> getOutConnections(int index) {
		return _outConnections.get(index);
	}
	public Connection getInConnection(int index) {
		return _inConnections.get(index);
	}
	public void newOutConnection(int srcIndex, int dstIndex,
			ProcessorNode dstNode) {
		ArrayList<Connection> connections = getOutConnections(srcIndex);
	    Connection conn = new Connection(this, srcIndex, dstNode, dstIndex);
		connections.add(conn);
		dstNode.setInConnection(conn, dstIndex);
	}
    boolean isOutConnectionExist(int srcIndex, int dstIndex,
			ProcessorNode dstNode){
    	boolean result = false;
		ArrayList<Connection> connections = getOutConnections(srcIndex);
	    Connection conn = new Connection(this, srcIndex, dstNode, dstIndex);
	    if(connections.contains(conn)){
	    	result = true;
	    }
		return result;
    }
	public void setInConnection(Connection conn, int inIndex) {
		_inConnections.set(inIndex, conn);
	}

	public void removeConnections() {
		for (int i = 0; i < _inConnections.size(); i++)
			_inConnections.get(i).disconnect();
		for (int i = 0; i < _outConnections.size(); i++) 
			for(int j = 0; j < _outConnections.get(i).size(); j++)
			  _outConnections.get(i).get(j).disconnect();	
	}
    public void deleteOutConnection(int srcOutIndex, Processor dstProc, int dstIndex){
    	ArrayList<Connection> conns = _outConnections.get(srcOutIndex);
    	int len = conns.size();
    	for(int i = 0; i < len; i++){
    		Connection conn = conns.get(i);
    		if(conn.getToNode().getProcessor() == dstProc &&
    				conn.getToIndex() == dstIndex){
    			conn.disconnect();
    			conns.remove(conn);
    		}
    	}
    }
	public int getNoInputs() {
		return _processor.getConnectionRule().getNoInputs();
	}

	public int getNoOutputs() {
		return _processor.getConnectionRule().getNoOutputs();
	}
	public boolean connected() {
		boolean result = true;
		for (int i = 0; i < _inConnections.size(); i++) {
			result &= _inConnections.get(i).connected() ;
		}
		//Outputs need not be connected for processing
		/*for (int i = 0; i < _outConnections.size(); i++) {
			int size = _outConnections.get(i).size();
			if(size == 0){
				result = false;
				break;
			}
			for(int j = 0; j < size; j++)
			  result &= _outConnections.get(i).get(j).connected();
		}*/
		return result;
	}
}
